package com.ideaaedi.springcloud.jd.commonspring.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.ideaaedi.springcloud.jd.commonds.constant.BaseConstant;
import com.ideaaedi.springcloud.jd.commonspring.config.properties.TenantProperties;
import com.ideaaedi.springcloud.jd.commonspring.mybatisplus.MybatisPlusInfoHolder;
import com.ideaaedi.springcloud.jd.commonspring.mybatisplus.tenant.LikeTenantLineInnerInterceptor;
import com.ideaaedi.springcloud.jd.commonspring.mybatisplus.tenant.TenantDataScopeBO;
import com.ideaaedi.springcloud.jd.commonspring.mybatisplus.tenant.TenantProvider;
import com.ideaaedi.springcloud.jd.commonspring.util.JdContextUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.LinkedHashSet;
import java.util.Objects;
import java.util.Set;

/**
 * MybatisPlus 配置
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 2021.0.1.A
 */
@Slf4j
@Configuration
public class MybatisPlusConfig {
    
    @Resource
    private MybatisPlusInfoHolder mybatisPlusInfoHolder;
    
    /**
     * 插件配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(TenantProperties tenantProperties) {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        if ( mybatisPlusInfoHolder.getTenantTables() == null) {
            mybatisPlusInfoHolder.initTenantTables();
        }
        Set<String> tenantTables = mybatisPlusInfoHolder.getTenantTables();
        
        if (!CollectionUtils.isEmpty(tenantTables)) {
            log.info("Exist tenantTables. LikeTenantLineInnerInterceptor auto been registered.");
            interceptor.addInnerInterceptor(new LikeTenantLineInnerInterceptor(new TenantLineHandler() {
                @Override
                public Expression getTenantId() {
                    TenantDataScopeBO tenantDataScopeBo = TenantProvider.TENANT_HOLDER.get();
                    if (tenantDataScopeBo != null && tenantDataScopeBo.getTenantDeque().size() > 0) {
                        String tenant = tenantDataScopeBo.getTenantDeque().peekFirst();
                        if (tenant != null) {
                            return new StringValue(tenant);
                        }
                    }
                    String currUserTenant = JdContextUtil.currUserTenant();
                    Objects.requireNonNull(currUserTenant, "LikeTenantLineInnerInterceptor tips: currUserTenant "
                            + "cannot be null.");
                    LinkedHashSet<String> readDataScopeSet = JdContextUtil.currUserDataScopeRead();
                    LinkedHashSet<String> updateDataScopeSet = JdContextUtil.currUserDataScopeUpdate();
                    return new StringValue(TenantDataScopeBO.buildTenantDataScopeStr(currUserTenant, readDataScopeSet, updateDataScopeSet));
                }
                
                @Override
                public String getTenantIdColumn() {
                    return BaseConstant.TENANT_COLUMN_NAME;
                }
                
                @Override
                public boolean ignoreTable(String tableName) {
                    if (tableName.contains(BaseConstant.MYSQL_ANTI_ESCAPE)) {
                        tableName = tableName.replace(BaseConstant.MYSQL_ANTI_ESCAPE, BaseConstant.EMPTY);
                    }
                    return !tenantTables.contains(tableName);
                }
            }, tenantProperties));
        }
        
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
    
}
